package com.techsen.maven.plugins.version;

import java.io.File;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.scm.ScmException;
import org.apache.maven.scm.ScmFileSet;
import org.apache.maven.scm.ScmResult;
import org.apache.maven.scm.manager.ScmManager;
import org.apache.maven.scm.provider.ScmProviderRepository;
import org.apache.maven.scm.repository.ScmRepository;
import org.apache.maven.scm.repository.ScmRepositoryException;
import org.codehaus.plexus.util.StringUtils;

import com.techsen.maven.plugins.util.PomHelper;

public abstract class AbstractScmMojo extends AbstractMojo {

    @Component
    protected ScmManager scmManager;

    @Parameter(defaultValue = "${project.basedir}", readonly = true, required = true)
    protected File basedir;

    @Parameter(defaultValue = "${project.parent.version}", readonly = true)
    protected String parentVersion;

    @Parameter(defaultValue = "${project.version}", readonly = true)
    protected String version;

    @Parameter(defaultValue = "${project.scm.developerConnection}", readonly = true, required = true)
    protected String developerConnection;

    @Parameter(defaultValue = "true", property = "useDefaultVersionUpdatePolicy")
    protected boolean useDefaultVersionUpdatePolicy;

    @Parameter(defaultValue = "^(?:\\d\\.){1,2}\\d-SNAPSHOT$", property = "snapshotVersionPattern")
    protected String snapshotVersionPattern;

    @Parameter(defaultValue = "^(?:\\d\\.){1,2}\\d$", property = "releaseVersionPattern")
    protected String releaseVersionPattern;
    
    @Parameter(defaultValue = "${project.version}", property = "tag.tagName")
    protected String tagName;

    /**
     * Push changes to remote scm repository
     */
    @Parameter(property = "pushChanges", defaultValue = "true")
    protected boolean pushChanges;

    public ScmRepository getScmRepository() throws ScmException {
        ScmRepository repository;
        try {
            repository = this.scmManager.makeScmRepository(this.developerConnection);
            ScmProviderRepository providerRepo = repository.getProviderRepository();
            providerRepo.setPushChanges(pushChanges);
        } catch (ScmRepositoryException e) {
            if (!e.getValidationMessages().isEmpty()) {
                for (String message : e.getValidationMessages()) {
                    getLog().error(message);
                }
            }
            throw new ScmException("Can't load the scm provider.", e);
        } catch (Exception e) {
            throw new ScmException("Can't load the scm provider.", e);
        }
        return repository;
    }

    public void checkResult(ScmResult result) throws MojoExecutionException {
        if (!result.isSuccess()) {
            getLog().error("Provider message:");
            getLog().error(result.getProviderMessage() == null ? "" : result.getProviderMessage());

            getLog().error("Command output:");
            getLog().error(result.getCommandOutput() == null ? "" : result.getCommandOutput());

            throw new MojoExecutionException(
                    "Command failed." + StringUtils.defaultString(result.getProviderMessage()));
        }
    }

    public ScmFileSet getFileSet() {
        return new ScmFileSet(this.basedir);
    }

    public PomHelper getPomHelper() {
        return new PomHelper(new File(this.basedir, "pom.xml"));
    }

    public boolean hasParentProject() {
        return StringUtils.isNotBlank(this.parentVersion);
    }

}
